package com.geovis.emergency.spd.biz.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geovis.common.auth.util.AuthUtil;
import com.geovis.common.core.constant.CommonConstants;
import com.geovis.common.socketio.dto.SocketIoMessage;
import com.geovis.common.socketio.service.ISocketIoService;
import com.geovis.emergency.spd.biz.agora.AgoraTokenDTO;
import com.geovis.emergency.spd.biz.agora.AgoraTokenUtil;
import com.geovis.emergency.spd.biz.app.mapper.AppDiscussMapper;
import com.geovis.emergency.spd.biz.app.service.AppDiscussService;
import com.geovis.emergency.spd.biz.app.service.AppDiscussStaffService;
import com.geovis.emergency.spd.biz.system.service.ISystemUserService;
import com.geovis.emergency.spd.entity.app.dto.AppDiscussDTO;
import com.geovis.emergency.spd.entity.app.dto.AppDiscussSaveDTO;
import com.geovis.emergency.spd.entity.app.entity.AppDiscuss;
import com.geovis.emergency.spd.entity.app.entity.AppDiscussStaff;
import com.geovis.emergency.spd.entity.app.enums.AppDiscussTypeEnum;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcDiscussConstant;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcMessageConstant;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDiscussSaveDTO;
import com.geovis.emergency.spd.entity.system.entity.SystemUser;
import com.geovis.emergency.spd.util.MsgUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class AppDiscussServiceImpl extends ServiceImpl<AppDiscussMapper, AppDiscuss> implements AppDiscussService {
    private final AppDiscussStaffService appDiscussStaffService;

    private final AgoraTokenUtil agoraTokenUtil;

    private final ISocketIoService socketIoService;

    private final ISystemUserService systemUserService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(AppDiscussSaveDTO saveDTO) {
        if(!StringUtils.hasText(saveDTO.getContent()))
        {
            saveDTO.setContent(saveDTO.getTitle());
        }
        // 1、获取所有的用户
        List<SystemUser> systemUserList = systemUserService.list(Wrappers.lambdaQuery(SystemUser.class).in(SystemUser::getId,saveDTO.getStaffIdList()));
        Map<String, SystemUser> systemUserMap = IterUtil.toMap(systemUserList, SystemUser::getId);

        // 2、保存会议
        AppDiscuss appDiscuss = BeanUtil.copyProperties(saveDTO, AppDiscuss.class);
        appDiscuss.setStartTime(LocalDateTime.now()).setStatus(PcDiscussConstant.STATUS_DOING).setCreatorId(AuthUtil.getCurrentUserId());

        save(appDiscuss);

        // 3、添加当前人入会议，构建参与会议人员信息，并入库
        saveDTO.getStaffIdList().add(AuthUtil.getCurrentUserId());
        List<AppDiscussStaff> staffList = saveDTO.getStaffIdList().stream().map(personId -> {

            AppDiscussStaff staff=  new AppDiscussStaff()
                    .setAppDiscussId(appDiscuss.getId()).setStatus(CommonConstants.NO)
                    .setPersonId(personId);
            if(null!=systemUserMap.get(personId))
            {
                staff.setPersonName(systemUserMap.get(personId).getRealName());
            }
            return staff;
        }).collect(Collectors.toList());
        appDiscussStaffService.saveBatch(staffList);

        // 4、发送消息
        Map<String, String> socketMap = MapUtil.newHashMap();
        socketMap.put("personName", AuthUtil.getCurrUser().getRealName());
//        socketIoService.sendMessage(SocketIoMessage.builder().
//                toUserIdSet(saveDTO.getStaffIdList()).eventName(PcMessageConstant.TYPE_DISCUSS_INVITATION).data(socketMap).build());
        saveDTO.getStaffIdList().stream().forEach(userId->{
            MsgUtil.pushMsgByUser(PcMessageConstant.TYPE_DISCUSS_INVITATION,saveDTO.getTitle(),saveDTO.getContent(),appDiscuss.getId(),appDiscuss.getId(),userId);
        });


    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public AgoraTokenDTO join(String appDiscussId) {
        AppDiscuss pcDiscuss = getById(appDiscussId);
        Assert.notNull(pcDiscuss, "该会议不存在!");
        Assert.isTrue(StrUtil.equals(pcDiscuss.getStatus(), PcDiscussConstant.STATUS_DOING), "该会议不是正在进行中的会议!");

        String currentUserId = AuthUtil.getCurrentUserId();
        AppDiscussStaff appDiscussStaff = appDiscussStaffService.getOne(Wrappers.lambdaQuery(AppDiscussStaff.class).eq(AppDiscussStaff::getAppDiscussId, appDiscussId)
                .eq(AppDiscussStaff::getPersonId, currentUserId));
        Assert.notNull(appDiscussStaff, "不好意思，您不在此次会议当中!");

        AgoraTokenDTO result = agoraTokenUtil.getToken(appDiscussId);
        appDiscussStaff.setStatus(CommonConstants.YES).setJoinTime(LocalDateTime.now()).setUid(result.getUid());
        appDiscussStaffService.updateById(appDiscussStaff);

        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void finish(String appDiscussId) {
        String currentUserId = AuthUtil.getCurrentUserId();
        AppDiscuss appDiscuss = getById(appDiscussId);
        Assert.notNull(appDiscuss, "该会议不存在!");
        Assert.isTrue(StrUtil.equals(appDiscuss.getCreatorId(), currentUserId), "您没有权限结束会议!");
        appDiscuss.setStatus(PcDiscussConstant.STATUS_FINISH).setEndTime(LocalDateTime.now());
        updateById(appDiscuss);

        // 发送消息
        //处置app是否需要发送消息
        List<AppDiscussStaff> pcDiscussStaffList = appDiscussStaffService.list(Wrappers.lambdaQuery(AppDiscussStaff.class).eq(AppDiscussStaff::getAppDiscussId, appDiscussId));
        socketIoService.sendMessage(SocketIoMessage.builder().
                toUserIdSet(pcDiscussStaffList.stream().map(AppDiscussStaff::getPersonId).collect(Collectors.toSet()))
                .eventName(PcMessageConstant.TYPE_DISCUSS_CREATE).data(appDiscuss.getId()).build());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void leave(String appDiscussId) {
        String currentUserId = AuthUtil.getCurrentUserId();
        AppDiscussStaff pcDiscussStaff = appDiscussStaffService.getOne(Wrappers.lambdaQuery(AppDiscussStaff.class).eq(AppDiscussStaff::getAppDiscussId, appDiscussId)
                .eq(AppDiscussStaff::getPersonId, currentUserId));
        Assert.notNull(pcDiscussStaff, "不好意思，您不在此会议当中!");
        pcDiscussStaff.setLeaveTime(LocalDateTime.now());
        appDiscussStaffService.updateById(pcDiscussStaff);
    }

    @Override
    public List<AppDiscussDTO> getList(AppDiscussTypeEnum discussType) {
        List<AppDiscuss> appDiscusses=this.list(Wrappers.lambdaQuery(AppDiscuss.class).eq(AppDiscuss::getDiscussType, discussType));
        return appDiscusses.stream().map(discuss->{
            AppDiscussDTO discussDTO=new AppDiscussDTO();
            BeanUtil.copyProperties(discuss,discussDTO);
            List<AppDiscussStaff> discussStaff = appDiscussStaffService.list(Wrappers.lambdaQuery(AppDiscussStaff.class).eq(AppDiscussStaff::getAppDiscussId, discuss.getId()));
            discussDTO.setStaffList(discussStaff);
            return discussDTO;

        }).collect(Collectors.toList());
    }




}
